<template>
  <view class="textarea" :class="[{ 'textarea--disabled': disabled }]">
    <view class="textarea__box">
      <view v-show="!isFoucs && !getTextLength" class="textarea__placeholder">
        <m-icon name="edit" size="28" color="inheirt" margin-right="8" />
        {{ placeholder }}
      </view>
      <textarea
        v-model="innerValue"
        class="textarea__textarea"
        :style="[getStyle]"
        :rows="rows"
        :disabled="disabled"
        :readonly="readonly"
        :maxlength="getFixMaxlength"
        :placeholder="' '"
        :focus="focus"
        :autoHeight="autoHeight"
        @input="handleInput"
        @blur="handleBlur"
        @focus="handleFocus"
      />
      <view v-if="limitShow" class="textarea__limit" :class="[`textarea__limit--${limitPosition}`]">
        <view>
          <text :class="{ 'has-value': getTextLength > 0 }">{{
            innerValue ? (getTextLength > maxlength ? maxlength : getTextLength) : getTextLength
          }}</text>
          /{{ maxlength }}
        </view>
      </view>
    </view>
    <view
      v-if="clearable && !readonly"
      class="textarea__box__close"
      :class="{ 'textarea__box__close--show': active && innerValue.length > 0 }"
      @click="handleClear"
    >
      <m-icon name="mask-close" size="28" color="#ccc" margin-right="8" />
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent, computed, reactive, toRefs, watch, inject } from '@vue/composition-api'
import { isAppPlus } from '@/utils/platform'

export default defineComponent({
  props: {
    value: {
      type: String,
      default: '',
    },
    textAlign: {
      type: String,
      default: 'left',
    },
    limitShow: {
      type: Boolean,
      default: true,
    },
    limitPosition: {
      type: String,
      default: 'left',
    },
    maxlength: {
      type: [String, Number],
      default: 80,
    },
    rows: {
      type: [String, Number],
      default: '',
    },
    placeholder: {
      type: String,
      default: '请输入内容',
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    height: {
      type: [String, Number],
      default: 120,
    },
    focus: {
      type: Boolean,
      default: false,
    },
    paddingBottom: {
      type: [String, Number],
      default: 0,
    },
    autoHeight: {
      type: Boolean,
      default: false,
    },
    clearable: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['input', 'change', 'blur', 'focus', 'clear'],
  setup(props, { emit }) {
    const formItem: any = inject('formItem', null)
    const state = reactive({
      innerValue: props.value,
      showEdit: true,
      isFoucs: false,
      active: false,
    })

    const getStyle = computed(() => {
      return {
        textAlign: props.textAlign,
        height: props.height + 'rpx',
        paddingBottom: props.paddingBottom + 'rpx',
      }
    })

    const getTextLength = computed(() => {
      return (state.innerValue || '').length
    })

    const getFixMaxlength = computed(() => {
      let maxlength = Number(props.maxlength)
      return maxlength
    })

    watch(
      () => props.value,
      (value) => {
        state.innerValue = value
      }
    )

    const handleClear = (event: Event) => {
      state.innerValue = ''
      emit('input', '', event)
      emit('change', '', event)
      emit('clear', '')
    }

    const emitChange = (value: string, event: Event) => {
      if (props.maxlength && value.length > Number(props.maxlength)) {
        value = value.substring(0, Number(props.maxlength))
      }
      emit('change', value, event)
      emit('input', value, event)
      try {
        if (formItem && formItem.validate) {
          formItem && formItem.validate()
        }
      } catch (ex) {}
    }

    const handleInput = (event: Event) => {
      const input = event.target as HTMLInputElement
      emitChange(input.value, event)
    }

    const handleFocus = (event: Event) => {
      if (props.disabled) return
      if (props.readonly) return
      state.active = true
      emit('focus', event)
      const input = event.target as HTMLInputElement
      let value = input.value
      emitChange(value, event)
      state.isFoucs = true
    }

    const handleBlur = (event: Event) => {
      setTimeout(() => {
        state.active = false
      }, 0)

      if (props.disabled) return
      if (props.readonly) return
      const input = event.target as HTMLInputElement
      let value = input.value

      state.isFoucs = false

      emitChange(value, event)
      emit('blur', { value, event })
    }

    return {
      ...toRefs(state),
      getStyle,
      getFixMaxlength,
      handleInput,
      handleFocus,
      handleBlur,
      handleClear,
      getTextLength,
    }
  },
})
</script>
<style lang="scss" scoped>
.textarea {
  position: relative;
  width: 100%;
  box-sizing: border-box;
  background: $--bg-content-c;
  font-size: rpx($--font-md-fz);
  color: $--font-primary-c;
  display: flex;
  align-items: center;
  border: 1px solid #f5f6f7;
  border-radius: 6rpx;
  padding-bottom: 20rpx;
  &__box {
    flex: 1;
    &__close {
      width: 32rpx;
      height: 32rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      &--show {
        opacity: 1;
      }
    }
  }
  &--disabled {
    .nut-textarea__textarea,
    .nut-textarea____limit {
      cursor: not-allowed;
      color: $--font-placeholder-c !important;
    }
  }
  &__limit {
    font-size: rpx($--font-sm-fz);
    color: $--font-placeholder-c;
    display: flex;
    &--left {
    }
    &--right {
      justify-content: flex-end;
    }
  }
  .has-value {
    color: $--font-primary-c;
    padding-right: 8rpx;
  }
  &__textarea {
    height: 200rpx;
    outline: none;
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 10rpx;
    font-size: rpx($--font-md-fz);
    text-align: left;
    background-color: transparent;
    border: 0;
    resize: none;
  }
  &__placeholder {
    position: absolute;
    /* #ifdef  MP-WEIXIN */
    top: 12rpx;
    /* #endif*/
    /* #ifndef MP-WEIXIN */
    top: 12rpx;
    /* #endif*/
    left: 12rpx;
    color: $--font-placeholder-c;
  }
}
</style>
